﻿using System;
using System.Collections.Generic;
using System.Text;
using CPF.Input;

namespace CPF.Windows
{
    public static class KeyInterop
    {
        private static readonly Dictionary<Keys, int> s_virtualKeyFromKey = new Dictionary<Keys, int>
        {
            { Keys.None, 0 },
            { Keys.Cancel, 3 },
            { Keys.Back, 8 },
            { Keys.Tab, 9 },
            { Keys.LineFeed, 0 },
            { Keys.Clear, 12 },
            { Keys.Return, 13 },
            { Keys.Pause, 19 },
            { Keys.Capital, 20 },
            { Keys.KanaMode, 21 },
            { Keys.JunjaMode, 23 },
            { Keys.FinalMode, 24 },
            { Keys.HanjaMode, 25 },
            { Keys.Escape, 27 },
            { Keys.ImeConvert, 28 },
            { Keys.ImeNonConvert, 29 },
            { Keys.ImeAccept, 30 },
            { Keys.ImeModeChange, 31 },
            { Keys.Space, 32 },
            { Keys.PageUp, 33 },
            { Keys.Next, 34 },
            { Keys.End, 35 },
            { Keys.Home, 36 },
            { Keys.Left, 37 },
            { Keys.Up, 38 },
            { Keys.Right, 39 },
            { Keys.Down, 40 },
            { Keys.Select, 41 },
            { Keys.Print, 42 },
            { Keys.Execute, 43 },
            { Keys.Snapshot, 44 },
            { Keys.Insert, 45 },
            { Keys.Delete, 46 },
            { Keys.Help, 47 },
            { Keys.D0, 48 },
            { Keys.D1, 49 },
            { Keys.D2, 50 },
            { Keys.D3, 51 },
            { Keys.D4, 52 },
            { Keys.D5, 53 },
            { Keys.D6, 54 },
            { Keys.D7, 55 },
            { Keys.D8, 56 },
            { Keys.D9, 57 },
            { Keys.A, 65 },
            { Keys.B, 66 },
            { Keys.C, 67 },
            { Keys.D, 68 },
            { Keys.E, 69 },
            { Keys.F, 70 },
            { Keys.G, 71 },
            { Keys.H, 72 },
            { Keys.I, 73 },
            { Keys.J, 74 },
            { Keys.K, 75 },
            { Keys.L, 76 },
            { Keys.M, 77 },
            { Keys.N, 78 },
            { Keys.O, 79 },
            { Keys.P, 80 },
            { Keys.Q, 81 },
            { Keys.R, 82 },
            { Keys.S, 83 },
            { Keys.T, 84 },
            { Keys.U, 85 },
            { Keys.V, 86 },
            { Keys.W, 87 },
            { Keys.X, 88 },
            { Keys.Y, 89 },
            { Keys.Z, 90 },
            { Keys.LWin, 91 },
            { Keys.RWin, 92 },
            { Keys.Apps, 93 },
            { Keys.Sleep, 95 },
            { Keys.NumPad0, 96 },
            { Keys.NumPad1, 97 },
            { Keys.NumPad2, 98 },
            { Keys.NumPad3, 99 },
            { Keys.NumPad4, 100 },
            { Keys.NumPad5, 101 },
            { Keys.NumPad6, 102 },
            { Keys.NumPad7, 103 },
            { Keys.NumPad8, 104 },
            { Keys.NumPad9, 105 },
            { Keys.Multiply, 106 },
            { Keys.Add, 107 },
            { Keys.Separator, 108 },
            { Keys.Subtract, 109 },
            { Keys.Decimal, 110 },
            { Keys.Divide, 111 },
            { Keys.F1, 112 },
            { Keys.F2, 113 },
            { Keys.F3, 114 },
            { Keys.F4, 115 },
            { Keys.F5, 116 },
            { Keys.F6, 117 },
            { Keys.F7, 118 },
            { Keys.F8, 119 },
            { Keys.F9, 120 },
            { Keys.F10, 121 },
            { Keys.F11, 122 },
            { Keys.F12, 123 },
            { Keys.F13, 124 },
            { Keys.F14, 125 },
            { Keys.F15, 126 },
            { Keys.F16, 127 },
            { Keys.F17, 128 },
            { Keys.F18, 129 },
            { Keys.F19, 130 },
            { Keys.F20, 131 },
            { Keys.F21, 132 },
            { Keys.F22, 133 },
            { Keys.F23, 134 },
            { Keys.F24, 135 },
            { Keys.NumLock, 144 },
            { Keys.Scroll, 145 },
            { Keys.LeftShift, 160 },
            { Keys.RightShift, 161 },
            { Keys.LeftCtrl, 162 },
            { Keys.RightCtrl, 163 },
            { Keys.LeftAlt, 164 },
            { Keys.RightAlt, 165 },
            { Keys.BrowserBack, 166 },
            { Keys.BrowserForward, 167 },
            { Keys.BrowserRefresh, 168 },
            { Keys.BrowserStop, 169 },
            { Keys.BrowserSearch, 170 },
            { Keys.BrowserFavorites, 171 },
            { Keys.BrowserHome, 172 },
            { Keys.VolumeMute, 173 },
            { Keys.VolumeDown, 174 },
            { Keys.VolumeUp, 175 },
            { Keys.MediaNextTrack, 176 },
            { Keys.MediaPreviousTrack, 177 },
            { Keys.MediaStop, 178 },
            { Keys.MediaPlayPause, 179 },
            { Keys.LaunchMail, 180 },
            { Keys.SelectMedia, 181 },
            { Keys.LaunchApplication1, 182 },
            { Keys.LaunchApplication2, 183 },
            { Keys.Oem1, 186 },
            { Keys.OemPlus, 187 },
            { Keys.OemComma, 188 },
            { Keys.OemMinus, 189 },
            { Keys.OemPeriod, 190 },
            { Keys.OemQuestion, 191 },
            { Keys.Oem3, 192 },
            { Keys.AbntC1, 193 },
            { Keys.AbntC2, 194 },
            { Keys.OemOpenBrackets, 219 },
            { Keys.Oem5, 220 },
            { Keys.Oem6, 221 },
            { Keys.OemQuotes, 222 },
            { Keys.Oem8, 223 },
            { Keys.OemBackslash, 226 },
            { Keys.ImeProcessed, 229 },
            { Keys.System, 0 },
            { Keys.OemAttn, 240 },
            { Keys.OemFinish, 241 },
            { Keys.OemCopy, 242 },
            { Keys.DbeSbcsChar, 243 },
            { Keys.OemEnlw, 244 },
            { Keys.OemBackTab, 245 },
            { Keys.DbeNoRoman, 246 },
            { Keys.DbeEnterWordRegisterMode, 247 },
            { Keys.DbeEnterImeConfigureMode, 248 },
            { Keys.EraseEof, 249 },
            { Keys.Play, 250 },
            { Keys.DbeNoCodeInput, 251 },
            { Keys.NoName, 252 },
            { Keys.Pa1, 253 },
            { Keys.OemClear, 254 },
            { Keys.DeadCharProcessed, 0 },
        };

        private static readonly Dictionary<int, Keys> s_keyFromVirtualKey = new Dictionary<int, Keys>
        {
            { 0, Keys.None },
            { 3, Keys.Cancel },
            { 8, Keys.Back },
            { 9, Keys.Tab },
            { 12, Keys.Clear },
            { 13, Keys.Return },
            { 16, Keys.LeftShift},
            { 17, Keys.LeftCtrl},
            { 18, Keys.LeftAlt },
            { 19, Keys.Pause },
            { 20, Keys.Capital },
            { 21, Keys.KanaMode },
            { 23, Keys.JunjaMode },
            { 24, Keys.FinalMode },
            { 25, Keys.HanjaMode },
            { 27, Keys.Escape },
            { 28, Keys.ImeConvert },
            { 29, Keys.ImeNonConvert },
            { 30, Keys.ImeAccept },
            { 31, Keys.ImeModeChange },
            { 32, Keys.Space },
            { 33, Keys.PageUp },
            { 34, Keys.Next },
            { 35, Keys.End },
            { 36, Keys.Home },
            { 37, Keys.Left },
            { 38, Keys.Up },
            { 39, Keys.Right },
            { 40, Keys.Down },
            { 41, Keys.Select },
            { 42, Keys.Print },
            { 43, Keys.Execute },
            { 44, Keys.Snapshot },
            { 45, Keys.Insert },
            { 46, Keys.Delete },
            { 47, Keys.Help },
            { 48, Keys.D0 },
            { 49, Keys.D1 },
            { 50, Keys.D2 },
            { 51, Keys.D3 },
            { 52, Keys.D4 },
            { 53, Keys.D5 },
            { 54, Keys.D6 },
            { 55, Keys.D7 },
            { 56, Keys.D8 },
            { 57, Keys.D9 },
            { 65, Keys.A },
            { 66, Keys.B },
            { 67, Keys.C },
            { 68, Keys.D },
            { 69, Keys.E },
            { 70, Keys.F },
            { 71, Keys.G },
            { 72, Keys.H },
            { 73, Keys.I },
            { 74, Keys.J },
            { 75, Keys.K },
            { 76, Keys.L },
            { 77, Keys.M },
            { 78, Keys.N },
            { 79, Keys.O },
            { 80, Keys.P },
            { 81, Keys.Q },
            { 82, Keys.R },
            { 83, Keys.S },
            { 84, Keys.T },
            { 85, Keys.U },
            { 86, Keys.V },
            { 87, Keys.W },
            { 88, Keys.X },
            { 89, Keys.Y },
            { 90, Keys.Z },
            { 91, Keys.LWin },
            { 92, Keys.RWin },
            { 93, Keys.Apps },
            { 95, Keys.Sleep },
            { 96, Keys.NumPad0 },
            { 97, Keys.NumPad1 },
            { 98, Keys.NumPad2 },
            { 99, Keys.NumPad3 },
            { 100, Keys.NumPad4 },
            { 101, Keys.NumPad5 },
            { 102, Keys.NumPad6 },
            { 103, Keys.NumPad7 },
            { 104, Keys.NumPad8 },
            { 105, Keys.NumPad9 },
            { 106, Keys.Multiply },
            { 107, Keys.Add },
            { 108, Keys.Separator },
            { 109, Keys.Subtract },
            { 110, Keys.Decimal },
            { 111, Keys.Divide },
            { 112, Keys.F1 },
            { 113, Keys.F2 },
            { 114, Keys.F3 },
            { 115, Keys.F4 },
            { 116, Keys.F5 },
            { 117, Keys.F6 },
            { 118, Keys.F7 },
            { 119, Keys.F8 },
            { 120, Keys.F9 },
            { 121, Keys.F10 },
            { 122, Keys.F11 },
            { 123, Keys.F12 },
            { 124, Keys.F13 },
            { 125, Keys.F14 },
            { 126, Keys.F15 },
            { 127, Keys.F16 },
            { 128, Keys.F17 },
            { 129, Keys.F18 },
            { 130, Keys.F19 },
            { 131, Keys.F20 },
            { 132, Keys.F21 },
            { 133, Keys.F22 },
            { 134, Keys.F23 },
            { 135, Keys.F24 },
            { 144, Keys.NumLock },
            { 145, Keys.Scroll },
            { 160, Keys.LeftShift },
            { 161, Keys.RightShift },
            { 162, Keys.LeftCtrl },
            { 163, Keys.RightCtrl },
            { 164, Keys.LeftAlt },
            { 165, Keys.RightAlt },
            { 166, Keys.BrowserBack },
            { 167, Keys.BrowserForward },
            { 168, Keys.BrowserRefresh },
            { 169, Keys.BrowserStop },
            { 170, Keys.BrowserSearch },
            { 171, Keys.BrowserFavorites },
            { 172, Keys.BrowserHome },
            { 173, Keys.VolumeMute },
            { 174, Keys.VolumeDown },
            { 175, Keys.VolumeUp },
            { 176, Keys.MediaNextTrack },
            { 177, Keys.MediaPreviousTrack },
            { 178, Keys.MediaStop },
            { 179, Keys.MediaPlayPause },
            { 180, Keys.LaunchMail },
            { 181, Keys.SelectMedia },
            { 182, Keys.LaunchApplication1 },
            { 183, Keys.LaunchApplication2 },
            { 186, Keys.Oem1 },
            { 187, Keys.OemPlus },
            { 188, Keys.OemComma },
            { 189, Keys.OemMinus },
            { 190, Keys.OemPeriod },
            { 191, Keys.OemQuestion },
            { 192, Keys.Oem3 },
            { 193, Keys.AbntC1 },
            { 194, Keys.AbntC2 },
            { 219, Keys.OemOpenBrackets },
            { 220, Keys.Oem5 },
            { 221, Keys.Oem6 },
            { 222, Keys.OemQuotes },
            { 223, Keys.Oem8 },
            { 226, Keys.OemBackslash },
            { 229, Keys.ImeProcessed },
            { 240, Keys.OemAttn },
            { 241, Keys.OemFinish },
            { 242, Keys.OemCopy },
            { 243, Keys.DbeSbcsChar },
            { 244, Keys.OemEnlw },
            { 245, Keys.OemBackTab },
            { 246, Keys.DbeNoRoman },
            { 247, Keys.DbeEnterWordRegisterMode },
            { 248, Keys.DbeEnterImeConfigureMode },
            { 249, Keys.EraseEof },
            { 250, Keys.Play },
            { 251, Keys.DbeNoCodeInput },
            { 252, Keys.NoName },
            { 253, Keys.Pa1 },
            { 254, Keys.OemClear },
        };

        public static Keys KeyFromVirtualKey(int virtualKey)
        {
            Keys result;
            s_keyFromVirtualKey.TryGetValue(virtualKey, out result);
            return result;
        }

        public static int VirtualKeyFromKey(Keys key)
        {
            int result;
            s_virtualKeyFromKey.TryGetValue(key, out result);
            return result;
        }
    }
}
